package com.firmail.global.advice;

import com.alibaba.fastjson.JSONException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.firmail.exception.FieldValidationException;
import com.firmail.exception.type.ExceptionType;
import com.firmail.mock.util.GsonUtils;
import com.firmail.response.ResponseInfo;
import com.firmail.utils.ResponseExceptionUtils;
import com.google.gson.stream.MalformedJsonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @Description 配置全局异常
 * @author asdf
 * @date 2018年9月12日 上午10:24:10
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public void error(HttpServletResponse response, Exception exception) {
        log.error("GlobalExceptionHandler ******* class- > {}, message-> {}", exception.getClass(), exception);
        PrintWriter writer = null;
        String message = exception.getMessage();
        try {
            writer = response.getWriter();
            ResponseInfo<String> info = new ResponseInfo<>();
            ExceptionType type = null;
            if (exception instanceof HttpMessageNotReadableException) {
                HttpMessageNotReadableException ex = (HttpMessageNotReadableException) exception;
                Throwable throwable = ex.getCause();
                if (throwable instanceof InvalidFormatException) {
                    type = ExceptionType.PARAMETER_ERROR_EXCEPTION;
                    info.setCode(type.getCode());

                } else if (throwable instanceof JsonMappingException) {
                    type = ExceptionType.PARAMETER_ERROR_EXCEPTION;
                } else {
                    type = ExceptionType.PARAMETER_ERROR_EXCEPTION;
                }
            } else if (exception instanceof MethodArgumentTypeMismatchException
                    || exception instanceof MissingServletRequestParameterException) {
                type = ExceptionType.PARAMETER_ERROR_EXCEPTION;
            /*} else if (exception instanceof VerificationCodeError3Exception) {// 验证码连续输入错误3次
                type = ExceptionType.VERIFICATION_FAIL_3;
            } else if (exception instanceof VerificationCodeSendErrorException) {// 验证码发送失败
                type = ExceptionType.VERIFICATION_SEND_FAIL;
            } else if (exception instanceof InvalidTokenException) {// token错误
                type = ExceptionType.TOKEN_ERROR_EXCEPTION;
            } else if (exception instanceof AccountLockException) {// 账户锁定
                type = ExceptionType.ACCOUNT_LOCK_ERROR;
            } else if (exception instanceof FrequentSendCodeException) {// 频繁发送验证码
                type = ExceptionType.FREQUENT_SEND_CODE;
            } else if (exception instanceof Login3FailuresException) {// 连续登录错误3次
                type = ExceptionType.LOGIN_FAIL_3;
            } else if (exception instanceof InvalidJSONException) {// json错误
                type = ExceptionType.PARAMETER_ERROR_EXCEPTION;*/
            } else if (exception instanceof HttpMediaTypeNotSupportedException) {// json错误
                type = ExceptionType.MEDIATYPE_NOT_SURPPORTED;
            } else if (exception instanceof FieldValidationException) {// 参数错误
                type = ExceptionType.INVALID_PARAMETER_EXCEPTION;
            } else if (exception instanceof MalformedJsonException) {// 参数无效MalformedJsonException
                type = ExceptionType.PARAMETER_INVALID_EXCEPTION;
                //type = ExceptionType.FILE_STATUS_DEL;
            } else if (exception instanceof JSONException) {// json解析错误
                type = ExceptionType.PARAMETER_ERROR_EXCEPTION;
            } else {
                type = ExceptionType.SYSTEM_EXCEPTION;
            }
            ResponseExceptionUtils.setException(info, type);
            info.setMessage(message);
            writer.println(GsonUtils.toJson(info));
            writer.flush();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}
